package org.eiahe.hr.employeeRelation.service.impl;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.ehe.common.core.domain.dto.StartProcessDTO;
import org.ehe.common.core.domain.dto.StartProcessReturnDTO;
import org.ehe.common.core.service.WorkflowService;
import org.ehe.common.core.utils.MapstructUtils;
import org.ehe.common.core.utils.StringUtils;
import org.ehe.erp.enums.ErpAuditStatus;
import org.ehe.system.domain.HrEmployee;
import org.ehe.system.domain.vo.HrEmployeeVo;
import org.ehe.system.mapper.HrEmployeeMapper;
import org.eiahe.hr.employeeRelation.domain.ContractInfo;
import org.eiahe.hr.employeeRelation.domain.ContractRenewalApplication;
import org.eiahe.hr.employeeRelation.domain.bo.ContractInfoBo;
import org.eiahe.hr.employeeRelation.domain.bo.ContractRenewalApplicationBo;
import org.eiahe.hr.employeeRelation.domain.vo.ContractInfoVo;
import org.eiahe.hr.employeeRelation.domain.vo.ContractRenewalApplicationVo;
import org.eiahe.hr.employeeRelation.mapper.ContractInfoMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.eiahe.hr.employeeRelation.mapper.ContractRenewalApplicationMapper;
import org.eiahe.hr.employeeRelation.service.IContractRenewalService;
import org.ehe.common.mybatis.core.page.PageQuery;
import org.ehe.common.mybatis.core.page.TableDataInfo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 合同续签服务实现类
 *
 * @author zhangnn
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class ContractRenewalServiceImpl implements IContractRenewalService {

    private final ContractInfoMapper contractInfoMapper;
    private final ContractRenewalApplicationMapper contractRenewalApplicationMapper;
    private final HrEmployeeMapper employeeMapper;
    private final WorkflowService workflowService;
    /**
     * 查询合同信息列表
     *
     * @param bo 合同信息业务对象
     * @return 合同信息列表
     */
    @Override
    public List<ContractInfoVo> selectContractInfoList(ContractInfoBo bo) {
        List<Long> employeeIds = new ArrayList<>();
        if (StringUtils.isNotBlank(bo.getEmployeeName())) {
            List<HrEmployee> hrEmployees = employeeMapper.selectList(new LambdaQueryWrapper<HrEmployee>()
                    .like(HrEmployee::getEmployeeName, bo.getEmployeeName()));
            employeeIds = hrEmployees.stream().map(HrEmployee::getEmployeeId).collect(Collectors.toList());
        }
        // 根据需要添加查询条件
        return this.contractInfoMapper.selectVoList(new LambdaQueryWrapper<ContractInfo>()
                .like(StringUtils.isNotBlank(bo.getEmployeeNo()), ContractInfo::getEmployeeNo, bo.getEmployeeNo())
                .in(StringUtils.isNotBlank(bo.getEmployeeName()), ContractInfo::getEmployeeId, employeeIds));
    }

    /**
     * 查询合同信息列表(分页)
     *
     * @param bo        合同信息业务对象
     * @param pageQuery 分页参数
     * @return 合同信息分页列表
     */
    @Override
    public TableDataInfo<ContractInfoVo> selectContractInfoList(ContractInfoBo bo, PageQuery pageQuery) {
        List<Long> employeeIds = new ArrayList<>();
        if (StringUtils.isNotBlank(bo.getEmployeeName())) {
            List<HrEmployee> hrEmployees = employeeMapper.selectList(new LambdaQueryWrapper<HrEmployee>()
                    .like(HrEmployee::getEmployeeName, bo.getEmployeeName()));
            employeeIds = hrEmployees.stream().map(HrEmployee::getEmployeeId).collect(Collectors.toList());
        }
        // 根据需要添加查询条件
        LambdaQueryWrapper<ContractInfo> lqw = new LambdaQueryWrapper<ContractInfo>()
                .like(StringUtils.isNotBlank(bo.getEmployeeNo()), ContractInfo::getEmployeeNo, bo.getEmployeeNo())
                .eq(StringUtils.isNotBlank(bo.getContractType()),ContractInfo::getContractType,bo.getContractType())
                .in(StringUtils.isNotBlank(bo.getEmployeeName()), ContractInfo::getEmployeeId, employeeIds)
                .orderByDesc(ContractInfo::getCreateTime);
        IPage<ContractInfoVo> page = contractInfoMapper.selectVoPage(pageQuery.build(), lqw);
        page.getRecords().forEach(e -> {
            Long employeeId = e.getEmployeeId();
            HrEmployeeVo hrEmployee = employeeMapper.selectVoById(employeeId);
            e.setEmployeeVo(hrEmployee);

            //如果到期时间距离当前日期小于30日或者超过10日内显示按钮
            long days = DateUtil.between(DateUtil.beginOfDay(new Date()), DateUtil.beginOfDay(e.getExpiryDate()), DateUnit.DAY);
            e.setRenewalButtonStatus((days < 30 && days > -11) ? "1" : "0");
        });
        return TableDataInfo.build(page);
    }

    /**
     * 通过合同ID查询合同信息
     *
     * @param contractId 合同ID
     * @return 合同信息
     */
    @Override
    public ContractInfoVo selectContractInfoById(Long contractId) {
        ContractInfoVo contractInfoVo = contractInfoMapper.selectVoById(contractId);
        //查询续签信息
        ContractRenewalApplicationBo bo = new ContractRenewalApplicationBo();
        bo.setContractId(contractId);
        bo.setEmployeeNo(contractInfoVo.getEmployeeNo());
        List<ContractRenewalApplicationVo> contractRenewalApplicationVos = this.selectContractRenewalApplicationList(bo);
        contractInfoVo.setContractRenewalApplicationVos(contractRenewalApplicationVos);

        HrEmployeeVo hrEmployee = employeeMapper.selectVoById(contractInfoVo.getEmployeeId());
        contractInfoVo.setEmployeeVo(hrEmployee);
        return contractInfoVo;
    }

    /**
     * 新增合同信息
     *
     * @param bo 合同信息业务对象
     * @return 结果
     */
    @Override
    public Boolean insertContractInfo(ContractInfoBo bo) {
        ContractInfo contractInfo = MapstructUtils.convert(bo, ContractInfo.class);
        return contractInfoMapper.insert(contractInfo) > 0;
    }

    /**
     * 修改合同信息
     *
     * @param bo 合同信息业务对象
     * @return 结果
     */
    @Override
    public Boolean updateContractInfo(ContractInfoBo bo) {
        ContractInfo contractInfo = MapstructUtils.convert(bo, ContractInfo.class);
        return contractInfoMapper.updateById(contractInfo) > 0;
    }

    /**
     * 批量删除合同信息
     *
     * @param contractIds 需要删除的合同ID数组
     * @return 结果
     */
    @Override
    public Boolean deleteContractInfoByIds(Long[] contractIds) {
        return contractInfoMapper.deleteBatchIds(Arrays.asList(contractIds)) > 0;
    }

    /**
     * 查询续签申请列表
     *
     * @param bo 续签申请业务对象
     * @return 续签申请列表
     */
    @Override
    public List<ContractRenewalApplicationVo> selectContractRenewalApplicationList(ContractRenewalApplicationBo bo) {

        System.out.println("contractId: " + bo.getContractId());
        System.out.println("employeeNo: " + bo.getEmployeeNo());

        List<ContractRenewalApplicationVo> contractRenewalApplicationVos =
            contractRenewalApplicationMapper.selectVoList(new LambdaQueryWrapper<ContractRenewalApplication>()
            .eq( ContractRenewalApplication::getContractId, bo.getContractId())
            .eq( ContractRenewalApplication::getEmployeeNo, bo.getEmployeeNo()));
        return contractRenewalApplicationVos;
    }

    /**
     * 查询续签申请列表(分页)
     *
     * @param bo        续签申请业务对象
     * @param pageQuery 分页参数
     * @return 续签申请分页列表
     */
    @Override
    public TableDataInfo<ContractRenewalApplicationVo> selectContractRenewalApplicationList(
            ContractRenewalApplicationBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<ContractRenewalApplication> lqw = Wrappers.lambdaQuery();
        lqw.eq(null != bo.getContractId(),ContractRenewalApplication::getContractId,bo.getContractId());
        // 根据需要添加查询条件
        IPage<ContractRenewalApplicationVo> page = contractRenewalApplicationMapper.selectVoPage(pageQuery.build(), lqw);

        return TableDataInfo.build(page);
    }

    private LambdaQueryWrapper<ContractInfoVo> buildQueryWrapper(ContractInfoBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<ContractInfoVo> lqw = Wrappers.lambdaQuery();
        lqw.like(StringUtils.isNotBlank(bo.getEmployeeNo()), ContractInfoVo::getEmployeeNo, bo.getEmployeeNo());

        lqw.orderByAsc(ContractInfoVo::getCreateTime);
        return lqw;
    }

    /**
     * 通过申请ID查询续签申请
     *
     * @param applicationId 申请ID
     * @return 续签申请
     */
    @Override
    public ContractRenewalApplicationVo selectContractRenewalApplicationById(Long applicationId) {
        return contractRenewalApplicationMapper.selectVoById(applicationId);
    }

    /**
     * 新增续签申请
     *
     * @param bo 续签申请业务对象
     * @return 结果
     */
    @Override
    public Boolean insertContractRenewalApplication(ContractRenewalApplicationBo bo) {
        ContractRenewalApplication application = MapstructUtils.convert(bo, ContractRenewalApplication.class);
        if (contractRenewalApplicationMapper.insert(application) > 0) {
            // 发起工作流程
//            if (bo.getApprovalStatus().equals(ErpAuditStatus.SUBMITTED.getStatus().toString())) {
//                StartProcessDTO process = new StartProcessDTO();
//                Map<String, Object> map = new HashMap<>();
//                map.put("type", "renewalTermination");
//                process.setVariables(map);
//                process.setFlowCode("renewalTermination");
//                process.setBusinessId(String.valueOf(application.getApplicationId()));
//                StartProcessReturnDTO processReturnDTO = workflowService.startWorkFlow(process);
//                log.info("流程审批发起成功，已启动: 合同终止={}, 员工编号={}", application.getApplicationId(), application.getEmployeeNo());
//
//                // 自己提交的流程节点默认审批完成
//                String employeeName = "";
//                HrEmployee hrEmployee = employeeMapper.selectOne(new LambdaQueryWrapper<HrEmployee>()
//                    .eq(HrEmployee::getEmployeeNo,bo.getEmployeeNo()));
//                if (Objects.nonNull(hrEmployee)) {
//                    employeeName = hrEmployee.getEmployeeName();
//                }
//                Long taskId = processReturnDTO.getTaskId();
//                workflowService.completeTask(taskId,
//                    "员工:" + employeeName +
//                        "编号:【" + application.getEmployeeNo() + "】" +
//                        "续签期限("+bo.getRenewalPeriod()+")月。备注:" + bo.getRenewalReason());
//            }
        }
        return true;
    }

    /**
     * 修改续签申请
     *
     * @param bo 续签申请业务对象
     * @return 结果
     */
    @Override
    public Boolean updateContractRenewalApplication(ContractRenewalApplicationBo bo) {
        ContractRenewalApplication application = MapstructUtils.convert(bo, ContractRenewalApplication.class);
        return contractRenewalApplicationMapper.updateById(application) > 0;
    }

    /**
     * 批量删除续签申请
     *
     * @param applicationIds 需要删除的申请ID数组
     * @return 结果
     */
    @Override
    public Boolean deleteContractRenewalApplicationByIds(Long[] applicationIds) {
        return contractRenewalApplicationMapper.deleteBatchIds(Arrays.asList(applicationIds)) > 0;
    }

    /**
     * 审批通过续签申请
     * 审批通过后自动：
     * 1. 更新续签申请的审批信息
     * 2. 将旧合同标记为“已续签”
     * 3. 生成一份新合同记录
     *
     * @param bo 续签申请业务对象
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean approveContractRenewal(ContractRenewalApplicationBo bo) {
        if (bo == null || bo.getApplicationId() == null || bo.getContractId() == null) {
            return false;
        }

        // 1. 更新续签申请的审批信息
        ContractRenewalApplication application = contractRenewalApplicationMapper.selectById(bo.getApplicationId());
        if (application == null) {
            return false; // 申请不存在，直接返回失败
        }


        LambdaUpdateWrapper<ContractRenewalApplication> applicationUpdate = Wrappers.lambdaUpdate();
        applicationUpdate.eq(ContractRenewalApplication::getApplicationId, bo.getApplicationId())
                .set(ContractRenewalApplication::getApproverId, bo.getApproverId())
                .set(ContractRenewalApplication::getApprovalTime, new Date())
                .set(ContractRenewalApplication::getApprovalRemark, bo.getApprovalRemark())
                .set(ContractRenewalApplication::getApprovalStatus, "1"); // 1-已通过
        contractRenewalApplicationMapper.update(null, applicationUpdate);

        // 2. 查询旧合同信息
        ContractInfo oldContract = contractInfoMapper.selectById(bo.getContractId());
        if (oldContract == null) {
            return false;
        }

        // 3. 更新旧合同的续签状态为“已续签”
        LambdaUpdateWrapper<ContractInfo> contractUpdate = Wrappers.lambdaUpdate();
        contractUpdate.eq(ContractInfo::getContractId, bo.getContractId())
                .set(ContractInfo::getRenewalStatus, "1"); // 1-已续签
        contractInfoMapper.update(null, contractUpdate);

        // 4. 生成新合同记录
        ContractInfo newContract = new ContractInfo();
        newContract.setUserId(oldContract.getUserId());
        newContract.setEmployeeId(oldContract.getEmployeeId());
        newContract.setEmployeeNo(oldContract.getEmployeeNo());
        newContract.setContractType(oldContract.getContractType());
        newContract.setSignDate(new Date()); // 新合同签订时间为当前时间
        newContract.setExpiryDate(application.getNewExpireDate());
        newContract.setRenewalStatus("0"); // 0-未续签
        newContract.setRenewalCount(oldContract.getRenewalCount() == null ? 1 : oldContract.getRenewalCount() + 1); // 续签次数+1
        newContract.setPrevContractId(oldContract.getContractId()); // 记录原合同ID
        newContract.setContractAttachment(oldContract.getContractAttachment());

        return contractInfoMapper.insert(newContract) > 0;
    }

    /**
     * 审批拒绝
     * @param bo
     * @return
     */
    @Override
    public Boolean rejectContractRenewal(ContractRenewalApplicationBo bo) {
        if (bo == null || bo.getApplicationId() == null || bo.getContractId() == null) {
            return false;
        }

        // 1. 更新续签申请的审批信息
        ContractRenewalApplication application = contractRenewalApplicationMapper.selectById(bo.getApplicationId());
        if (application == null) {
            return false; // 申请不存在，直接返回失败
        }

        LambdaUpdateWrapper<ContractRenewalApplication> applicationUpdate = Wrappers.lambdaUpdate();
        applicationUpdate.eq(ContractRenewalApplication::getApplicationId, bo.getApplicationId())
            .set(ContractRenewalApplication::getApproverId, bo.getApproverId())
            .set(ContractRenewalApplication::getApprovalTime, new Date())
            .set(ContractRenewalApplication::getApprovalRemark, bo.getApprovalRemark())
            .set(ContractRenewalApplication::getApprovalStatus, "2"); // 1-已驳回
        contractRenewalApplicationMapper.update(null, applicationUpdate);
        return true;
    }
}
